#pragma once
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Log.hpp"
#include "InetAddr.hpp"
#include "Comm.hpp"
#include "nocopy.hpp"

const static uint16_t defaultport=8888;
const static int defaultfd=-1;
const static int defaultsize=1024;

class UdpServer:public nocopy
{
public:
    UdpServer(uint16_t port=defaultport)
    :_port(port),_sockfd(defaultfd)
    {}
 
    void Init()
    {
        //创建socket，就是创建了文件细节
        _sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockfd<0)
        {
            lg.LogMessage(Fatal,"socket err,%d :%s\n",errno,strerror(errno));
            exit(Socket_Err);
        }
        lg.LogMessage(Info,"socket success,socketfd:%d",_sockfd);
        //绑定上网信息
        struct sockaddr_in local;
        bzero(&local,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(_port);
        local.sin_addr.s_addr=INADDR_ANY;

        //结构体填完，接下来设置到内核
        int n=bind(_sockfd,(struct sockaddr*)&local,sizeof(local));
        if(n!=0)
        {
            lg.LogMessage(Fatal,"bind error,%d:%s\n",errno,sizeof(local));
            exit(Bind_Err);
        }

    }
    void Start()
    {
        char buffer[defaultsize];
        for(;;)
        {
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);
            ssize_t n=recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            if(n>0)
            {
                InetAddr addr(peer);
                buffer[n]=0;
                cout<<'['<<addr.PrintDebug()<<']'<<buffer<<endl;
                sendto(_sockfd,buffer,strlen(buffer),0,(struct sockaddr*)&peer,len);
            }
        }
    }
    ~UdpServer()
    {}
private:
    uint16_t _port;
    int _sockfd;
};
